using System;
using System.Collections.Generic;
using offline2048;
using MotionFramework.Event;
using UnityEngine;
using UnityEngine.Purchasing;

public class IAPMgr : MonoSingleton<IAPMgr>, IStoreListener
{
    /// <summary>
    /// 
    /// </summary>
    private Action<PurchaseResult, string, PurchaseEventArgs> _iapCallBack = null;

    /// <summary>
    /// 
    /// </summary>
    private Action<RestoreResult, string> _restoreCallBack = null;

    /// <summary>
    /// 
    /// </summary>
    private IStoreController controller;

#if UNITY_IOS
    /// <summary>
    /// 
    /// </summary>
    private IAppleExtensions extensions;
#endif

#if UNITY_ANDROID
    /// <summary>
    /// 
    /// </summary>
    private IGooglePlayStoreExtensions extensions;
#endif

    /// <summary>
    /// 是否完成初始化
    /// </summary>
    private bool _isInited = false;

    /// <summary>
    /// 内购iap
    /// </summary>
    private List<string> _iapKeys = new List<string>();

    /// <summary>
    /// 内购价格
    /// </summary>
    private Dictionary<string, string> _priceDic = new Dictionary<string, string>();

    /// <summary>
    /// 玩家一次restore操作成功恢复的商品商品数量(restore操作结束后置0)
    /// </summary>
    private int _restoreProductsCnt = 0;

    /// <summary>
    /// 初始化尝试次数
    /// </summary>
    private int _initTryTimes = 0;

    /// <summary>
    /// 查询商店初始化状态
    /// </summary>
    public bool IsInited
    {
        get { return _isInited; }
    }

    /// <summary>
    /// 初始化
    /// </summary>
    public void Init(List<string> iapKeys)
    {
        _iapKeys = iapKeys;
        Init();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="iapKey"></param>
    /// <returns></returns>
    public string GetPrice(string iapKey)
    {
        if (_priceDic.ContainsKey(iapKey))
        {
            return _priceDic[iapKey];
        }
        return null;
    }

    /// <summary>
    /// 发起购买
    /// </summary>
    /// <param name="productId"></param>
    public void Purchase(string iapKey, Action<PurchaseResult, string, PurchaseEventArgs> iapCallBack)
    {
        if (_isInited)
        {
            GTA.ADSHelper.IsTryPlayAD = true;
            
            _iapCallBack = iapCallBack;

            GameLogger.Log(MotionFramework.Console.GameLogType.IAP, "开始内购：" + GetIAProductKey(iapKey));

            //UITools.ShowConnecting(15);

            controller.InitiatePurchase(GetIAProductKey(iapKey));
        }
        else
        {
            GameLogger.Log(MotionFramework.Console.GameLogType.IAP, "内购初始化失败!");
            if (iapCallBack != null)
            {
                iapCallBack(PurchaseResult.NotInit, iapKey, null);
            }
        }
    }
    
    /// <summary>
    /// 成功恢复一个商品
    /// </summary>
    public void RestoreOneProduct()
    {
        _restoreProductsCnt++;

        GameLogger.Log(MotionFramework.Console.GameLogType.IAP,
            $"[测试 Restore] RestoreOneProduct _restoreProductsCnt:{_restoreProductsCnt}");
    }

    /// <summary>
    /// restore操作结束后置0
    /// </summary>
    public void ResetRestoreProductsCnt()
    {
        _restoreProductsCnt = 0;

        GameLogger.Log(MotionFramework.Console.GameLogType.IAP, $"[测试 Restore] _restoreProductsCnt 清零");
    }

    /// <summary>
    /// 初始化
    /// </summary>
    private void Init()
    {
        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

        for (int i = 0; i < _iapKeys.Count; i++)
        {
            string iapkey = GetIAProductKey(_iapKeys[i]);
            //int _id = i + 1;
            CfgShop table = ConfigManager.Instance.GetShopData(_iapKeys[i]);//CfgShop.GetConfigTable(i + 1);
            if (table == null)
            {
                continue;
            }
            //非消耗品
            /*if (table.IAP_Type == 1)
            {
                builder.AddProduct(iapkey, ProductType.NonConsumable);
            }
            //消耗品
            else
            {
                builder.AddProduct(iapkey, ProductType.Consumable);
            }*/
            builder.AddProduct(table.IAP_Key, ProductType.Consumable);
        }
        UnityPurchasing.Initialize(this, builder);
    }

    public string CurrencyCode { get; private set; } = "";

    /// <summary>
    /// 初始化成功
    /// </summary>
    /// <param name="controller"></param>
    /// <param name="extensions"></param>
    public void OnInitialized(IStoreController controller, IExtensionProvider provider)
    {
        GameLogger.Log(MotionFramework.Console.GameLogType.IAP, "内购初始化成功!");
        this.controller = controller;

        foreach (var item in controller.products.all)
        {
            CurrencyCode = item.metadata.isoCurrencyCode;
            if (!string.IsNullOrEmpty(CurrencyCode))
            {
                break;
            }
        }
        

#if UNITY_IOS
        extensions = provider.GetExtension<IAppleExtensions>();
#endif

#if UNITY_ANDROID
        extensions = provider.GetExtension<IGooglePlayStoreExtensions>();
#endif

        for (int i = 0; i < _iapKeys.Count; i++)
        {
            var item = controller.products.WithID(GetIAProductKey(_iapKeys[i]));
            if (item != null)
            {
                if (!_priceDic.ContainsKey(_iapKeys[i]))
                {
                    _priceDic.Add(_iapKeys[i], item.metadata.localizedPriceString);
                }
                else
                {
                    _priceDic[_iapKeys[i]] = item.metadata.localizedPriceString;
                }
            }
        }

        _isInited = true;

        //EventManager.Instance.SendMessage(new ShopEvent.InitSuc());
    }

    /// <summary>
    /// 初始化失败
    /// </summary>
    /// <param name="error"></param>
    public void OnInitializeFailed(InitializationFailureReason error)
    {
        _initTryTimes++;
        if (_initTryTimes <= 2)
        {
            Debug.LogError("内购初始化失败:" + error.ToString());
        }
        //重新初始化
        Init();
    }

    public void OnInitializeFailed(InitializationFailureReason error, string message)
    {
        _initTryTimes++;
        if (_initTryTimes <= 2)
        {
            Debug.LogError($"内购初始化失败:{message} , " + error.ToString());
        }
        //重新初始化
        // Init(); 
    }

    /// <summary>
    /// 购买失败
    /// </summary>
    /// <param name="product"></param>
    /// <param name="failureReason"></param>
    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    {
        GameLogger.Log(MotionFramework.Console.GameLogType.IAP, "购买失败!");
        //UITools.HideConnecting();
        
        //正常购买失败
        if (_iapCallBack != null)
        {
            PurchaseResult purchaseResult = PurchaseResult.Unknown;
            switch (failureReason)
            {
                case PurchaseFailureReason.PurchasingUnavailable:
                    purchaseResult = PurchaseResult.PurchasingUnavailable;
                    break;
                case PurchaseFailureReason.ExistingPurchasePending:
                    purchaseResult = PurchaseResult.ExistingPurchasePending;
                    break;
                case PurchaseFailureReason.ProductUnavailable:
                    purchaseResult = PurchaseResult.ProductUnavailable;
                    break;
                case PurchaseFailureReason.SignatureInvalid:
                    purchaseResult = PurchaseResult.SignatureInvalid;
                    break;
                case PurchaseFailureReason.UserCancelled:
                    purchaseResult = PurchaseResult.UserCancelled;
                    break;
                case PurchaseFailureReason.PaymentDeclined:
                    purchaseResult = PurchaseResult.PaymentDeclined;
                    break;
                case PurchaseFailureReason.DuplicateTransaction:
                    purchaseResult = PurchaseResult.DuplicateTransaction;
                    break;
                case PurchaseFailureReason.Unknown:
                    purchaseResult = PurchaseResult.Unknown;
                    break;
            }
            _iapCallBack(purchaseResult, "", null);
            _iapCallBack = null;
        }
        //restore失败
        else if (_restoreCallBack != null)
        {
            _restoreCallBack(RestoreResult.Failed, "");
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="purchaseEvent"></param>
    /// <returns></returns>
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
    {
        GameLogger.Log(MotionFramework.Console.GameLogType.IAP, "购买成功回调" + purchaseEvent.purchasedProduct.definition.id);
        string productId = purchaseEvent.purchasedProduct.definition.id;//purchaseEvent.purchasedProduct.definition.id.Replace(ExtraStr, "");
        
        //a.正常购买成功(通用逻辑)
        if (_iapCallBack != null)
        {
            //UITools.HideConnecting();
            _iapCallBack(PurchaseResult.Success, productId, purchaseEvent);
            _iapCallBack = null;
            
            return PurchaseProcessingResult.Complete;
        }
        
 #if UNITY_IOS
        //b.手动restore成功(仅iOS)
        if (_restoreCallBack != null)
        {
            _restoreCallBack(RestoreResult.Success, productId);
            _restoreCallBack = null;

            return PurchaseProcessingResult.Complete;
        }
        
#elif UNITY_ANDROID
        //自动restore(仅Andorid)
        else
        {
            GameLogger.Log(MotionFramework.Console.GameLogType.IAP, $"自动restore productId : {productId}");

            //DataManager.Instance.GetData<DataIAP>().RecordRestoreItem(productId);
        }
#endif
        
        return PurchaseProcessingResult.Complete;
    }

    public string ExtraStr
    {
        get { return Application.identifier + '_'; }
    }


    /// <summary>
    /// 转化商店道具key值
    /// </summary>
    /// <param name="iapkey"></param>
    /// <returns></returns>
    public string GetIAProductKey(string iapkey)
    {
        //return Application.identifier + '_' + iapkey;
        return iapkey;
    }
}

/// <summary>
/// 
/// </summary>
public enum PurchaseResult
{
    /// <summary>
    /// 成功
    /// </summary>
    Success = 1,

    /// <summary>
    /// 没有初始化
    /// </summary>
    NotInit = 2,

    PurchasingUnavailable = 3,
    ExistingPurchasePending = 4,
    ProductUnavailable = 5,
    SignatureInvalid = 6,
    UserCancelled = 7,
    PaymentDeclined = 8,
    DuplicateTransaction = 9,
    Unknown = 10,
}

/// <summary>
/// 
/// </summary>
public enum RestoreResult
{
    /// <summary>
    /// 成功
    /// </summary>
    Success = 1,

    /// <summary>
    /// 失败
    /// </summary>
    Failed = 2,

    /// <summary>
    /// 没有初始化
    /// </summary>
    NotInit = 3,
}